home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HAM Radio 1997
/
HAM Radio 1997.iso
/
vcls
/
resizer
/
resizer.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1996-04-08
|
9KB
|
281 lines
{*
* NO THIS IS NOT PERFECT. IF YOU DON'T LIKE IT, DON'T USE IT!
*
* This is a simple VC that resizes all the controls on a form.
*
* All you have to do is place the RESIZER component on your form,
* set the 'OnSized' event for the form to a function and then call
* 'ReSize(Sender)' from within that function.
*
* It is a GOOD IDEA in your 'OnSized' event for the form to watch
* for resizing that is too small. If you resize the form too small
* you can cause this Resizer to crash your program. All you have to
* do is check the bounds of the form being resized, if they are less
* than a certain amount, set the bounds to the certain amount.
*
* See the example program for help or you can mail me:
* mental@murdrum.nmsu.edu
*
* Obvious extensions are adding support to any container controls I
* may have missed. You can tell if something is a container control
* by placing another control on it and then try to move the control
* outside of it. If you cannot move the inner control outside, it
* IS a container control.
* I have NOT figured out how controls are stored on a TTabbedNotebook,
* (but honently I have not looked very hard, yet) so while the
* TTabbedNotebook will resize itself, the obejcts on the pages will
* not size themselvess.
*}
unit Resizer;
interface
uses
SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
Forms, Dialogs, ExtCtrls, StdCtrls, TabNotBk;
type
pControlInfo = ^tControlInfo;
tControlInfo = record
{ This record holds information about a component on the form}
{ or about a component inside a container object}
Obj:TControl;
ClassName:String;
lRatio,tRatio,wRatio,hRatio:Real;
Contains:pControlInfo;
Next:pControlInfo;
End;
TResizer = class(TComponent)
private
{ These variables and functions should not be needed by the user, }
{ only by the RESIZER component.}
ResizerInitialized:Boolean;
Function GetClientControlCount(Sender:TObject):LongInt;
procedure GetNewWidthHeight(Sender:TObject;Var NewW,NewH:LongInt);
Procedure PerformResize(CurCont:pControlInfo;CWidth,CHeight:LongInt);
Function GetClientControlObject(Sender:TObject;Index:LongInt):TControl;
Function Initialize(Sender:TObject;CWidth,CHeight:LongInt):pControlInfo;
Procedure DeleteControlList(CurCont:pControlInfo);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
{ These are useful to the programmer. I currently dont use NewShapshot, but}
{ somebody out there might.... especially if you are using DYNAMICALLY}
{ created components on your form.}
procedure ReSize(ParentForm:TObject);
procedure NewSnapshot(ParentForm:TObject);
end;
procedure Register;
implementation
Var ControlList:pControlInfo;
constructor TResizer.Create(AOwner: TComponent);
Var Count:LongInt;
Begin
inherited Create(AOwner);
{ Do my init stuff}
ResizerInitialized:=False;
ControlList:=nil;
End;
destructor TResizer.Destroy;
Begin
{ Destroy the existing ControlList }
DeleteControlList(ControlList);
ResizerInitialized:=False;
ControlList:=nil;
inherited Destroy;
End;
{ Recursively setup throw the control list and all containers}
{ and delete all the dynamically allocated objects}
Procedure TResizer.DeleteControlList(CurCont:pControlInfo);
Var NextCont:pControlInfo;
Begin
While(CurCont<>nil) Do
Begin
If((CurCont^.Contains)<>nil) Then
DeleteControlList(CurCont^.Contains);
NextCont:=CurCont^.Next;
FreeMem(CurCont,SizeOf(tControlInfo));
CurCont:=NextCont;
End;
End;
procedure TResizer.GetNewWidthHeight(Sender:TObject;Var NewW,NewH:LongInt);
Begin
{ Determine the type of container component we have then get its}
{ width and height and tag number}
If(Sender is TForm) Then
With TForm(Sender) Do
Begin
{ Since this is a TForm, we want ClientWidth and ClientHeight}
NewW:=ClientWidth;
NewH:=ClientHeight;
End
Else
If(Sender is TPanel) Then
With TPanel(Sender) Do
Begin
NewW:=Width;
NewH:=Height;
End
Else
If(Sender is TGroupBox) Then
With TGroupBox(Sender) Do
Begin
NewW:=Width;
NewH:=Height;
End
Else
{The TTabbedNotebook stuff doesn't work right... Components inside}
{the tabbed notebook won't resize as of yet}
If(Sender is TTabbedNotebook) Then
With TTabbedNotebook(Sender) Do
Begin
NewW:=Width;
NewH:=Height;
End
Else
Begin
{ We don't recognize the container, so supply 0 values}
NewW:=0;
NewH:=0;
End;
End;
Function TResizer.GetClientControlCount(Sender:TObject):LongInt;
Begin
{ Determine the type of container component we have then}
{ return the number of controls on that container}
If(Sender is TForm) Then
Result:=TForm(Sender).ControlCount
Else
If(Sender is TPanel) Then
Result:=TPanel(Sender).ControlCount
Else
If(Sender is TGroupBox) Then
Result:=TGroupBox(Sender).ControlCount
Else
{The TTabbedNotebook stuff doesn't work right... Components inside}
{the tabbed notebook won't resize as of yet}
If(Sender is TTabbedNotebook) Then
Result:=TTabbedNotebook(Sender).ControlCount
Else
{ We don't recognize the container, so supply a 0 value}
Result:=0;
End;
Function TResizer.GetClientControlObject(Sender:TObject;Index:LongInt):TControl;
Begin
If(Sender is TForm) Then
Result:=TForm(Sender).Controls[Index]
Else
If(Sender is TPanel) Then
Result:=TPanel(Sender).Controls[Index]
Else
If(Sender is TGroupBox) Then
Result:=TGroupBox(Sender).Controls[Index]
Else
{The TTabbedNotebook stuff doesn't work right... Components inside}
{the tabbed notebook won't resize as of yet}
If(Sender is TTabbedNotebook) Then
Result:=TTabbedNotebook(Sender).Controls[Index]
Else
Result:=nil;
End;
Function TResizer.Initialize(Sender:TObject;CWidth,CHeight:LongInt):pControlInfo;
Var Temp:pControlInfo;
Count:Integer;
Begin
Result:=nil;
For Count:=0 to (GetClientControlCount(Sender)-1) Do
Begin
GetMem(Temp,SizeOf(tControlInfo));
Temp^.Obj:=GetClientControlObject(Sender,Count);
With(Temp^) Do
Begin
lRatio:=(Obj.Left) / CWidth;
tRatio:=(Obj.Top) / CHeight;
wRatio:=(Obj.Width) / CWidth;
hRatio:=(Obj.Height) / CHeight;
Contains:=nil;
Next:=Result;
End;
Result:=Temp;
{The TTabbedNotebook stuff doesn't work right... Components inside}
{the tabbed notebook won't resize as of yet}
If((Temp^.Obj is TForm) or
(Temp^.Obj is TPanel) or
(Temp^.Obj is TGroupBox) or
(Temp^.Obj is TTabbedNotebook)) Then
With(Temp^) Do
Contains:=Initialize(Obj,Obj.Width,Obj.Height);
End;
End;
Procedure TResizer.PerformResize(CurCont:pControlInfo;CWidth,CHeight:LongInt);
Begin
While(CurCont<>nil) Do
Begin
With(CurCont^) Do
Begin
With(Obj) Do
SetBounds(Round(lRatio*CWidth),Round(tRatio*CHeight),
Round(wRatio*CWidth),Round(hRatio*CHeight));
If(Contains<>nil) Then
PerformResize(Contains,Obj.Width,Obj.Height);
End;
CurCont:=CurCont^.Next;
End;
End;
procedure TResizer.NewSnapshot(ParentForm:TObject);
Var NewClientWidth,NewClientHeight:LongInt;
Begin
GetNewWidthHeight(ParentForm,NewClientWidth,NewClientHeight);
{ Delete the existing ControlList for this form}
DeleteControlList(ControlList);
ControlList:=nil;
ResizerInitialized:=False;
{ Initialize the ControlList for this form}
ControlList:=Initialize(ParentForm,NewClientWidth,NewClientHeight);
If(ControlList<>nil) Then
{ The control list HAS been initialized!}
ResizerInitialized:=True;
End;
{ This should be called everytime the form is resized (ie in the OnSized}
{ event). Pass OnSized "Sender" parameter to this procedure}
procedure TResizer.ReSize(ParentForm:TObject);
Var NewClientWidth,NewClientHeight:LongInt;
Count:Integer;
Left,Top,Width,Height:LongInt;
Begin
GetNewWidthHeight(ParentForm,NewClientWidth,NewClientHeight);
If(ResizerInitialized) Then
{ The ControlList already exists, resize the form and its controls}
PerformResize(ControlList,NewClientWidth,NewClientHeight)
Else
{ No ControlList exists. Let's create one}
NewSnapshot(ParentForm);
End;
{ This should be called only if you want to take a NEW shapshot of the}
{ relative positions and sizes of the controls on the form. The paramter}
{ should be the form on which the object resides}
procedure Register;
begin
{ Register the RESIZER component}
RegisterComponents('New VCs', [TResizer]);
end;
end.